﻿using System;
using System.Collections.Generic;
using System.Linq;
using AMM.CustomClassLibrary;
using AMM.DataAccess.Business;
using AMM.DataAccess.Project;
using AMM.DataAccess.Store;
using AMM.Model;
using AMM.Model.Project;

namespace AMM.Business.Project {
    public class MaterialProcessor : BaseProcessor {

        private int _pageSize;
        private MaterialRepository _materialRepository;
        private ProcurementOrderRepository _procurementOrderRepository;

        public MaterialProcessor(int pageSize = int.MaxValue) {
            this._pageSize = pageSize;
            this._materialRepository = new MaterialRepository(pageSize);
            this._procurementOrderRepository = new ProcurementOrderRepository(int.MaxValue);
        }

        public Material FetchMaterialById(int materialId) {
            try {
                return this._materialRepository.FetchMaterialById(materialId);
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("获取指定物料资料数据失败！");
            }
        }

        public List<Material> FetchMaterialList() {
            try {
                return this._materialRepository.FetchMaterialList();
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("获取物料资料列表失败！");
            }
        }

        public List<MaterialViewModel> FetchMaterialViewModelListByVendorId(int vendorId) {
            try {
                List<Quotation> resultList = new QuotationRepository(int.MaxValue).FetchQuotationsByVendorId(vendorId);
                return resultList.Select(x => {
                    return new MaterialViewModel() {
                        Key = x.Material.MaterialId,
                        MaterialType = x.Material.Basic.Name,
                        Code = x.Material.Code,
                        Name = x.Material.Name,
                        Remarks = x.Material.Remarks
                    };
                }).ToList();
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("获取物料资料列表失败！");
            }
        }

        public List<MaterialViewModel> FetchMaterialViewModelListByProcumentOrderId(int procurementOrderId) {
            try {
                List<ProcurementOrderDetail> resultList =
                    new ProcurementOrderRepository(int.MaxValue).FetchMaterialViewModelListByProcumentOrderId(procurementOrderId);
                return resultList.Select(x => {
                    return new MaterialViewModel() {
                        Key = x.Material.MaterialId,
                        MaterialType = x.Material.Basic.Name,
                        Code = x.Material.Code,
                        Name = x.Material.Name,
                        Remarks = x.Material.Remarks
                    };
                }).ToList();
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("获取物料资料列表失败！");
            }
        }

        public List<MaterialViewModel> FetchMaterialViewModelListBySuspenseOrderId(int suspenseOrderId) {
            try {
                List<SuspenseOrderDetail> resultList =
                    new SuspenseOrderRepository(int.MaxValue).FetchMaterialViewModelListBySuspenseOrderId(suspenseOrderId);
                return resultList.Select(x => {
                    return new MaterialViewModel() {
                        Key = x.Material.MaterialId,
                        MaterialType = x.Material.Basic.Name,
                        Code = x.Material.Code,
                        Name = x.Material.Name,
                        Remarks = x.Material.Remarks
                    };
                }).ToList();
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("获取物料资料列表失败！");
            }
        }

        public List<MaterialViewModel> FetchMaterialViewModelListByProduceConductId(int produceConductId) {
            try {
                List<BOMDetail> resultList =
                    new ProduceConductRepository(int.MaxValue).FetchProduceConductBOMMaterialList(produceConductId);
                return resultList.Select(x => {
                    return new MaterialViewModel() {
                        Key = x.Material.MaterialId,
                        MaterialType = x.Material.Basic.Name,
                        Code = x.Material.Code,
                        Name = x.Material.Name,
                        Remarks = x.Material.Remarks
                    };
                }).ToList();
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("获取物料资料列表失败！");
            }
        }

        public List<MaterialViewModel> FetchMaterialViewModelList(MaterialSearchModel searchModel, int pageIndex = 1) {
            try {
                List<Material> resultList = this._materialRepository.FetchMaterialList(searchModel, pageIndex);
                return resultList.Select(x => {
                    return new MaterialViewModel() {
                        Key = x.MaterialId,
                        MaterialType = x.Basic.Name,
                        Unit = x.Basic1.Name,
                        Code = x.Code,
                        Name = x.Name,
                        Remarks = x.Remarks,
                        PreserveAmount = x.PreserveAmount,
                        IsEnabled = x.IsEnabled,
                        IsAttach = x.AttachmentId.HasValue,
                        CreatedBy = x.CreatedBy,
                        CreatedDatetime = x.CreatedDatetime,
                        ModifiedBy = x.ModifiedBy,
                        ModifiedDatetime = x.ModifiedDatetime
                    };
                }).ToList();
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("获取物料资料列表失败！");
            }
        }

        public void Insert(Material material) {
            try {
                material.MaterialId = Guid.NewGuid().GetHashCode();
                material.CreatedDatetime = DateTime.Now;
                this._materialRepository.Insert(material);
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("插入新物料资料失败！");
            }
        }

        public void Update(Material material) {
            try {
                Material oldMaterial = this.FetchMaterialById(material.MaterialId);
                if (!oldMaterial.RowVersion.SequenceEqual(material.RowVersion)) {
                    throw this.BuildException("更新物料资料失败，数据不一致性错误！");
                }
                material.ModifiedDatetime = DateTime.Now;
                this._materialRepository.Update(material, oldMaterial);
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("更新物料资料失败！");
            }
        }

        public void Delete(Material material) {
            try {
                this._materialRepository.Delete(material);
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("删除物料资料失败！");
            }
        }

        public void Delete(params int[] materialIds) {
            try {
                this._materialRepository.DeleteMultipleMaterial(materialIds);
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("删除物料资料失败！");
            }
        }
    }
}
